package com.example.tangyee.fragment;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;

import com.example.circular_progress_button.CircularProgressButton;
import com.example.tangyee.MainActivity;
import com.example.tangyee.R;
import com.example.tangyee.utils.SessionidUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class LoginFragment extends Fragment {
    private static final String  TAG = "LoginFragment";

    private Unbinder mUnbinder;

    // 跟踪登录（后台）任务，确保我们可以在需要时取消它。
    private UserLoginTask mAuthTask = null;

    @BindView(R.id.phone_num)
    AutoCompleteTextView mPhoneNumView;
    @BindView(R.id.password)
    EditText mPasswordView;
    @BindView(R.id.sign_in_button)
    CircularProgressButton mSignInButton;

    public static LoginFragment newInstance() {
        return new LoginFragment();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_login, container, false);
        mUnbinder = ButterKnife.bind(this, v);

        // 建立一个登陆表单
        mPasswordView.setOnEditorActionListener((textView, id, keyEvent) -> {
            if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
                attemptLogin();
                return true;
            }
            return false;
        });

        mSignInButton.setIndeterminateProgressMode(true); // 进入不精准进度模式
        mSignInButton.setOnClickListener(v1 -> attemptLogin());

        return v;
    }

    /**
     * 尝试登陆
     */
    private void attemptLogin() {
        if (mAuthTask != null) {
            return;
        }

        // 关闭输入法
        InputMethodManager inputMethodManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);

        //接受软键盘输入的编辑文本或其它视图
//        inputMethodManager.showSoftInput(submitBt,InputMethodManager.SHOW_FORCED);


        // 重置错误信息
        mPhoneNumView.setError(null);
        mPasswordView.setError(null);

        // 保存/提取这次尝试登陆的账号和密码
        String username = mPhoneNumView.getText().toString();
        String password = mPasswordView.getText().toString();

        // 是否取消登陆
        boolean cancel = false;

        // 用于提示账密格式错误信息的 视图
        View focusView = null;

        // 用户未输入密码
        if (TextUtils.isEmpty(password)) {
            mPasswordView.setError(getString(R.string.error_no_password));
            focusView = mPasswordView;
            cancel = true;
        }

        // 如果用户输入了密码，检查它是否有效
        if (TextUtils.isEmpty(password) && !isPasswordValid(password)) {
            mPasswordView.setError(getString(R.string.error_invalid_password));
            // 错误视图在密码输入框，原因是 密码太短
            focusView = mPasswordView;

            // 确定取消登陆
            cancel = true;
        }

        // 检查是否为有效的账号格式
        if (TextUtils.isEmpty(username)) {
            mPhoneNumView.setError(getString(R.string.error_field_required));
            focusView = mPhoneNumView;
            cancel = true;
        } else if (!isPhoneNumValid(username)) {
            mPhoneNumView.setError(getString(R.string.error_invalid_phone_number));
            focusView = mPhoneNumView;
            cancel = true;
        }

        // 当cancel为true时，说明输入的账密格式有误，显示错误信息到错误提示框
        if (cancel) {
            // 登陆表单有错，不再试图登陆，先提示错误
            // 表单字段有误 则显示错误信息
            focusView.requestFocus();
        } else {
            // 显示一个进度圈，同时开始一个后台任务
            // 执行用户登陆的意图
            showProgress(true);

            mAuthTask = new UserLoginTask(username, password);
            mAuthTask.execute((Void) null);
        }
    }

    private boolean isPhoneNumValid(String phoneNum) {
        return phoneNum.length() >= 4;
    }

    private boolean isPasswordValid(String password) {
        return password.length() > 4;
    }

    /**
     * 展示进度UI并隐藏登陆表格
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
    private void showProgress(final boolean show) {

        if (show) {
            // 按钮不可点击
            mSignInButton.setClickable(false);
            // 显示进度条
            mSignInButton.setProgress(50);
        } else {
            // 还原按钮
            mSignInButton.setProgress(0);
            mSignInButton.setClickable(true);
        }
    }

    /**
     * 表示 用户（账密格式无误的） 的一个异步 登陆/注册 任务
     */
    public class UserLoginTask extends AsyncTask<Void, Void, String> {

        private final String mUsername;
        private final String mPassword;

        UserLoginTask(String username, String password) {
            mUsername = username;
            mPassword = password;
        }

        @Override
        protected String doInBackground(Void... params) {

            OkHttpClient okHttpClient = new OkHttpClient();

            RequestBody body = new FormBody.Builder()
                    .add("user", mUsername)
                    .add("pwd", mPassword)
                    .build();

            Request request = new Request.Builder()
                    .url("https://www.tangyee.com/Mobile/Login")
                    .post(body)
                    .build();

            try {
                Response response = okHttpClient.newCall(request).execute();
                if (response.isSuccessful()) {
                    Log.d(TAG, "doInBackground: " + response.body().toString());
                    return response.body().string();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;

        }

        @Override
        protected void onPostExecute(final String response) {
            mAuthTask = null;

            if (response == null) {
                showProgress(false);
                Snackbar.make(getView(), "登陆失败，请检查网络。", Snackbar.LENGTH_LONG).setAction("Action", null).show();
                return;
            }

            try {
                Log.i(TAG, "Received JSON: " + response);
                JSONObject jsonBody = new JSONObject(response);
                if (jsonBody.getInt("state") == 4) {
                    SessionidUtils.setSessionId(getActivity(), jsonBody.getString("sessionid"), mUsername, mPassword);
                    loginSuccess();
                } else {
                    showProgress(false);
                    mPasswordView.setError(getString(R.string.error_incorrect_password));
                    mPasswordView.requestFocus();
                }
            } catch (JSONException je) {
                Log.e(TAG, "Failed to parse JSON", je);
                Snackbar.make(getView(), "登陆失败，服务器繁忙。", Snackbar.LENGTH_LONG).setAction("Action", null).show();
                showProgress(false);
            }

        }

        @Override
        protected void onCancelled() {
            mAuthTask = null;
            showProgress(false);
        }
    }

    private void loginSuccess() {
        Intent intent = new Intent(getActivity(), MainActivity.class);
        startActivity(intent);
        getActivity().finish();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mUnbinder != null) {
            mUnbinder.unbind();
        }
    }
}
